package com.sita.cfmoto.support;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.sita.cfmoto.utils.LogUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by hongyun on 2016/3/2.
 */

public class LocationController {
    private static final int MODE_NORMAL = 0;
    private static final int MODE_TRACING = 1;
    private static int mMode = 0;
    private static final String TAG = LocationController.class.getSimpleName();

    private static AMapLocationClient locationClientOnce = null;
    private static AMapLocationClientOption locationClientOptionOnce = null;
    private static AMapLocationClient locationClientNormal = null;
    private static AMapLocationClientOption locationOptionNormal = null;
    private static AMapLocationClient locationClientTracking = null;
    private static AMapLocationClientOption locationOptionTracking = null;
    private static AMapLocationClient locationClientUpload = null;
    private static AMapLocationClientOption locationClientOptionUpload = null;
    private static List<AMapLocationListener> mTrackingListenerList = new ArrayList<>();

    private static Intent alarmIntent = null;
    private static PendingIntent alarmPi = null;
    private static AlarmManager alarm = null;
    private static long updateGeoInterval = 1000 * 60 * 60 * 24;
    private static long updateGeoAlarmInterval = 100 * 60 * 60;


    private static void doLog() {
        LogUtils.i(TAG, "ClientNormal: " + ((locationClientNormal == null) ? "NO" : ("OK, Service:" + (locationClientNormal.isStarted() ? "started" : "stopped"))));
        LogUtils.i(TAG, "ClientTracing: " + ((locationClientTracking == null) ? "NO" : ("OK, Service:" + (locationClientTracking.isStarted() ? "started" : "stopped"))));
        LogUtils.i(TAG, "ClientOnce: " + ((locationClientOnce == null) ? "NO" : ("OK, Service:" + (locationClientOnce.isStarted() ? "started" : "stopped"))));

    }

    public static AMapLocation getLastKnownLocation() {
        doLog();
        if (locationClientTracking != null && locationClientTracking.isStarted()) {
            return locationClientTracking.getLastKnownLocation();
        } else if (locationClientNormal != null && locationClientNormal.isStarted()) {
            return locationClientNormal.getLastKnownLocation();
        } else if (locationClientOnce != null) {
            return locationClientOnce.getLastKnownLocation();
        }
        return null;
    }

    public static void initLocationController() {
        // should start at the application startup
        startLocationClientOnce();
//        startLocationClientUpload();  // disable for Yadea now;
    }

    // TODO: 2016/3/5 should be removed later, consumer no need to get access of the location client directly
    public static AMapLocationClient getLocationClient() {
        doLog();
        if (locationClientTracking != null && locationClientTracking.isStarted()) {
            return locationClientTracking;
        } else if (locationClientNormal != null && locationClientNormal.isStarted()) {
            return locationClientNormal;
        } else if (locationClientOnce != null) {
            return locationClientOnce;
        }
        return null;
    }

    public static void startLocationClientOnce(AMapLocationListener listener) {
        locationClientOnce = new AMapLocationClient(GlobalContext.getGlobalContext());
        locationClientOptionOnce = new AMapLocationClientOption();

        locationClientOptionOnce.setLocationMode(AMapLocationClientOption.AMapLocationMode.Battery_Saving);
        locationClientOptionOnce.setOnceLocation(true);
        locationClientOptionOnce.setNeedAddress(true);
        /**
         * 设置是否优先返回GPS定位结果，如果30秒内GPS没有返回定位结果则进行网络定位
         * 注意：只有在高精度模式下的单次定位有效，其他方式无效
         */
        // 设置发送定位请求的时间间隔,最小值为1000，如果小于1000，按照1000算
        locationClientOptionOnce.setInterval(1000);
        locationClientOnce.setLocationOption(locationClientOptionOnce);
        locationClientOnce.startLocation();
        locationClientOnce.setLocationListener(listener);
    }

    public static void startLocationClientOnce() {
        locationClientOnce = new AMapLocationClient(GlobalContext.getGlobalContext());
        locationClientOptionOnce = new AMapLocationClientOption();

        locationClientOptionOnce.setLocationMode(AMapLocationClientOption.AMapLocationMode.Battery_Saving);
        locationClientOptionOnce.setOnceLocation(true);
        locationClientOptionOnce.setNeedAddress(true);
        /**
         * 设置是否优先返回GPS定位结果，如果30秒内GPS没有返回定位结果则进行网络定位
         * 注意：只有在高精度模式下的单次定位有效，其他方式无效
         */
        // 设置发送定位请求的时间间隔,最小值为1000，如果小于1000，按照1000算
        locationClientOptionOnce.setInterval(1000);
        locationClientOnce.setLocationOption(locationClientOptionOnce);
        locationClientOnce.startLocation();
        locationClientOnce.setLocationListener(new AMapLocationListener() {
            @Override
            public void onLocationChanged(AMapLocation aMapLocation) {
                if (aMapLocation == null || aMapLocation.getErrorCode() != 0) {
                    LogUtils.d(TAG, "no location found yet, error:" + ((aMapLocation != null) ? aMapLocation.getErrorInfo() : ""));
                } else {
                    LogUtils.d(TAG, "get location good");
                }
            }
        });

    }

    private static void startLocationClientUpload() {
        locationClientUpload = new AMapLocationClient(GlobalContext.getGlobalContext());
        locationClientOptionUpload = new AMapLocationClientOption();

        locationClientOptionUpload.setLocationMode(AMapLocationClientOption.AMapLocationMode.Battery_Saving);
        locationClientOptionUpload.setNeedAddress(true);
        // 设置发送定位请求的时间间隔,最小值为1000，如果小于1000，按照1000算
        locationClientOptionUpload.setInterval(updateGeoInterval);
        locationClientUpload.setLocationOption(locationClientOptionUpload);
        locationClientUpload.startLocation();
        locationClientUpload.setLocationListener(new AMapLocationListener() {
            @Override
            public void onLocationChanged(final AMapLocation aMapLocation) {

                if (aMapLocation.getErrorCode() == 0) {
                    LogUtils.d(TAG, "location upload");
                    /*final UpdateGeoRequest request = new UpdateGeoRequest();
                    request.accountId = account;
                    request.location = new Location();
                    request.location.longitude = String.valueOf(aMapLocation.getLongitude());
                    request.location.latitude = String.valueOf(aMapLocation.getLatitude());
                    request.location.province = aMapLocation.getProvince();
                    request.location.city = aMapLocation.getCity();
                    request.location.time = String.valueOf(System.currentTimeMillis());

                    RestClient.getRestNormalService().updateGeo(request, new Callback<RestResponse>() {
                        @Override
                        public void success(RestResponse restResponse, Response response) {
                            LogUtils.d(TAG, "update geo ok, error code:" + restResponse.mErrorCode);
                            LocalStorage.saveLastUpdateGeoDatetime(Long.valueOf(request.location.time));
                        }

                        @Override
                        public void failure(RetrofitError error) {
                            L.e("startLocationClientUpload()", error);
                        }
                    });
*/
                }
            }
        });
//
//        // 创建Intent对象，action为LOCATION
//        alarmIntent = new Intent();
//        alarmIntent.setAction("LOCATION");
//        IntentFilter ift = new IntentFilter();
//
//        // 定义一个PendingIntent对象，PendingIntent.getBroadcast包含了sendBroadcast的动作。
//        // 也就是发送了action 为"LOCATION"的intent
//        alarmPi = PendingIntent.getBroadcast(GlobalContext.getGlobalContext(), 0, alarmIntent, 0);
//        // AlarmManager对象,注意这里并不是new一个对象，AlarmManager为系统级服务
//        alarm = (AlarmManager) GlobalContext.getGlobalContext().getSystemService(Context.ALARM_SERVICE);
//
//        //动态注册一个广播
//        IntentFilter filter = new IntentFilter();
//        filter.addAction("LOCATION");
//        GlobalContext.getGlobalContext().registerReceiver(alarmReceiver, filter);
//        alarm.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 2 * 1000,
//                updateGeoAlarmInterval, alarmPi);
    }

//    private static BroadcastReceiver alarmReceiver = new BroadcastReceiver() {
//        @Override
//        public void onReceive(Context context, Intent intent) {
//            if (intent.getAction().equals("LOCATION")) {
//                LogUtils.d(TAG, "get alarm trigger");
//                long duration = System.currentTimeMillis() - LocalStorage.getLastUpdateGeoDatetime();
//                if (null != locationClientUpload && duration > updateGeoInterval) {
//                    LogUtils.d(TAG, "triggered by alarm");
//                    locationClientUpload.startLocation();
//                }
//            }
//        }
//    };

    /*
     * should only called by Application
     */
    public static void destroyLocationClient() {

        if (locationClientNormal != null) {
            locationClientNormal.onDestroy();
            locationClientNormal = null;
        }

        if (locationClientTracking != null) {
            locationClientTracking.onDestroy();
            locationClientTracking = null;
        }

        if (locationClientOnce != null) {
            locationClientOnce.onDestroy();
            locationClientOnce = null;
        }

        if (locationClientUpload != null) {
            locationClientUpload.onDestroy();
            locationClientUpload = null;
        }
    }

    public static void startTracking(AMapLocationListener listener, long interval) {
        LogUtils.d(TAG, "location client startTracking mode");
        if (locationClientTracking == null) {
            initTrackingLocationClient(interval);
        }

        locationClientTracking.startLocation();
//        if (!mTrackingListenerList.contains(listener)) {
            locationClientTracking.setLocationListener(listener);
//            mTrackingListenerList.add(listener);
//        }

        pauseNormal();
        doLog();
    }

    public static void stopTracking(AMapLocationListener listener) {
        LogUtils.d(TAG, "location client stopTracking mode");
        if (locationClientTracking != null) {
            locationClientTracking.unRegisterLocationListener(listener);
//            mTrackingListenerList.remove(listener);
//            if (mTrackingListenerList.size() == 0) {
                locationClientTracking.stopLocation();
                restoreNormal();
//            }
        }

        doLog();
    }

    public static void startNormal(AMapLocationListener listener) {
        LogUtils.d(TAG, "location client startNormal mode");
        if (locationClientNormal == null) {
            initNormalLocationClient();
        }
        locationClientNormal.startLocation();
        locationClientNormal.setLocationListener(listener);
        doLog();
    }

    public static void stopNormal(AMapLocationListener listener) {
        LogUtils.d(TAG, "location client stopNormal mode");
        if (locationClientNormal != null) {
            locationClientNormal.stopLocation();
            locationClientNormal.unRegisterLocationListener(listener);
        }
        doLog();
    }

    private static void pauseNormal() {
        if (locationClientNormal != null) {
            locationClientNormal.stopLocation();
        }
    }

    private static void restoreNormal() {
        if (locationClientNormal != null) {
            locationClientNormal.startLocation();
        }
    }

    private static void initTrackingLocationClient(long interval) {
        locationClientTracking = new AMapLocationClient(GlobalContext.getGlobalContext());
        locationOptionTracking = new AMapLocationClientOption();
        // 设置定位模式为高精度模式
        locationOptionTracking.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        locationOptionTracking.setOnceLocation(false);
        locationOptionTracking.setNeedAddress(false);
        /**
         * 设置是否优先返回GPS定位结果，如果30秒内GPS没有返回定位结果则进行网络定位
         * 注意：只有在高精度模式下的单次定位有效，其他方式无效
         */
        locationOptionTracking.setGpsFirst(true);
        // 设置发送定位请求的时间间隔,最小值为1000，如果小于1000，按照1000算
        locationOptionTracking.setInterval(interval);

        locationClientTracking.setLocationOption(locationOptionTracking);
    }

    private static void initNormalLocationClient() {
        locationClientNormal = new AMapLocationClient(GlobalContext.getGlobalContext());
        locationOptionNormal = new AMapLocationClientOption();
        // 设置定位模式为高精度模式
        locationOptionNormal.setLocationMode(AMapLocationClientOption.AMapLocationMode.Battery_Saving);
        locationOptionNormal.setOnceLocation(false);
        locationOptionNormal.setNeedAddress(true);
        // 设置发送定位请求的时间间隔,最小值为1000，如果小于1000，按照1000算
        locationOptionNormal.setInterval(1000 * 60);
        locationClientNormal.setLocationOption(locationOptionNormal);
    }

    public static String getLocationString() {
        String locString = "";
        AMapLocation location = getLastKnownLocation();
        if (location != null) {
            locString = String.valueOf(location.getLatitude()) + "," +
                    String.valueOf(location.getLongitude());
        }
        return locString;
    }

    public static String getLocationAddress() {
        String addressString = "";
        AMapLocation location = getLastKnownLocation();
        if (location != null) {
            addressString = location.getAddress();
        }
        return addressString;
    }
}
